#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
int n,m,L,V;
struct Node
{
    int d;
    int v;
    int a;
};
set<int> open;
vector<int> need;
vector<Node> car;
int test[MAXN]={-1};
/*
long long do_v(int v,int a,int t)
{
    return v+a*t;
}
long long do_s(int v,int a,int t)
{
    return v*t+0.5*a*t*t;
}
*/
bool do_fi(int v,int a,int s)
{
    long long now=v*v+2*a*s;
    //cout<<now<<endl;
    if(now>V*V) return true;
    else return false;
}
void init()
{
    cin>>n>>m>>L>>V;
    for(int i=0;i<n;i++)
    {
        int fir,sec,the;
        cin>>fir>>sec>>the;
        car.push_back((Node){fir,sec,the});
    }
    for(int i=0;i<m;i++)
    {
        int fir;
        cin>>fir;
        test[i]=fir;
    }
    sort(test,test+m);
}
void doit_first()
{
    int tot=0;
    for(int i=0;i<n;i++)
    {
        Node now=car[i];
        if(now.a==0)
        {
            if(now.v>V && now.d<=test[m-1])
            {
                tot++;
                need.push_back(i);
            }
        }
        if(now.a>0)
        {
            if(now.d>test[m-1]) continue;
            if(do_fi(now.v,now.a,test[m-1]-now.d))
            {
                tot++;
                need.push_back(i);
            }
        }
    }
    cout<<tot<<' ';
}
void cle()
{
    open.clear();
    car.clear();
    memset(test,-1,sizeof(test));
    need.clear();
}
void doit_second()
{
    int ans=0;
    for(int i=0;i<need.size();i++)
    {
        Node now=car[ need[i] ];
        if(now.a>=0)
        {
            int last=open.size();
            open.insert(test[m-1]);
            if(open.size()>last) ans++;
        }
    }
    cout<<m-ans<<endl;
}
int main()
{
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    int t;
    cin>>t;
    for(int i=0;i<t;i++)
    {
        init();
        doit_first();
        doit_second();
        cle();
    }
    return 0;
}
